package com.wujunshen.swagger.exception;

import com.wujunshen.swagger.web.vo.response.BaseResponse;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author frank woo(吴峻申) <br>
 * email:<a href="mailto:frank_wjs@hotmail.com">frank_wjs@hotmail.com</a> <br>
 * @date 2020/2/7 5:33 下午 <br>
 * 如果返回的为json数据或其它对象，添加该注解
 */
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler { // 添加全局异常处理流程，根据需要设置需要处理的异常
    
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public Object methodArgumentNotValidHandler(MethodArgumentNotValidException exception) {
        // 按需重新封装需要返回的错误信息
        List<ArgumentInvalidResult<Object>> invalidArguments =
                exception.getBindingResult().getFieldErrors().stream()
                        .map(this::getInvalidArgument)
                        .collect(Collectors.toList());
        
        BaseResponse<List<ArgumentInvalidResult<Object>>> baseResponse = new BaseResponse<>();
        baseResponse.setCode(ResponseStatus.PARAMETER_ERROR.getCode());
        baseResponse.setMessage(ResponseStatus.PARAMETER_ERROR.getMessage());
        baseResponse.setData(invalidArguments);
        return baseResponse;
    }
    
    /**
     * 解析原错误信息，封装后返回，此处返回非法的字段名称，原始值，错误信息
     *
     * @param error FieldError
     * @return ArgumentInvalidResult<Object>
     */
    private ArgumentInvalidResult<Object> getInvalidArgument(FieldError error) {
        ArgumentInvalidResult<Object> invalidArgument = new ArgumentInvalidResult<>();
        invalidArgument.setDefaultMessage(error.getDefaultMessage());
        invalidArgument.setField(error.getField());
        invalidArgument.setRejectedValue(error.getRejectedValue());
        return invalidArgument;
    }
}
